package com.rambler.fileupload.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.rambler.common.utils.IDUtil;
import com.rambler.fileupload.config.OSSProperties;
import com.rambler.api.fileupload.dto.FileMetadata;
import com.rambler.api.fileupload.dto.FileUploadDTO;
import com.rambler.fileupload.entity.SysFileInfo;
import com.rambler.fileupload.service.FileUploadService;
import com.rambler.api.fileupload.vo.FileUploadVO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author suhao
 */
@Service
@Slf4j
public class OSSFileUploadServiceImpl implements FileUploadService {

    @Resource
    private OSSClient ossClient;

    @Resource
    private OSSProperties ossProperties;

    @Override
    public SysFileInfo uploadFile(MultipartFile file, String path, FileUploadDTO dto) {

        SysFileInfo fileInfo = new SysFileInfo();

        // 1️ 获取bucket和上传的文件夹
        int index = path.indexOf('/');
        String bucketName = "", filePath = "";
        if (index != -1) {
            bucketName = path.substring(0, index);
            filePath = path.substring(index + 1);
        }
        // 2️ 重新命名文件名
        String fileId = IDUtil.randomUUID();
        FileMetadata fileMetadata = dto.getFileMetadata();
        String newFileName = fileId + "." + fileMetadata.getExtension();
        // 更新元信息
        fileInfo.setId(fileId);
        fileInfo.setFileKey(fileId);
        // 3️ 上传到OSS, 生成可访问外链
        try {
            ObjectMetadata meta = new ObjectMetadata();
            if (dto.getIsPublic() == 1) {
                meta.setObjectAcl(CannedAccessControlList.PublicRead);
            } else {
                meta.setObjectAcl(CannedAccessControlList.Private);
            }
            String destPath = filePath + "/" + newFileName;
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, destPath, file.getInputStream(), meta);
            ossClient.putObject(putObjectRequest);
            fileInfo.setUrl(generateDirectUrl(bucketName, destPath));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 4️ 更新文件信息
        fileInfo.setStorageType("oss");
        fileInfo.setStoragePath(path);
        fileInfo.setIsPublic(dto.getIsPublic());
        fileInfo.setBizType(path);
        return fileInfo;
    }

    @Override
    public List<FileUploadVO> batchUploadFile(List<MultipartFile> files, String path, FileUploadDTO dto) {
        return List.of();
    }

    @Override
    public Boolean deleteFile(String fileId) {
        return null;
    }

    @Override
    public FileUploadVO getFileInfo(String fileId) {
        return null;
    }

    @Override
    public void deleteBatch(List<String> fileIds) {
    }

    @Override
    public boolean exists(String fileId) {
        return false;
    }

    @Override
    public boolean supports(String uploadType) {
        return "oss".equalsIgnoreCase(uploadType);
    }

    // 生成访问外链
    private String generateDirectUrl(String bucketName, String filePath) {
        Map<String, String> bucketDomainMap = ossProperties.getBucketDomainMap();
        if (!bucketDomainMap.containsKey(bucketName)) {
            return "";
        }
        String domain = bucketDomainMap.get(bucketName);
        return domain + "/" + filePath;
    }

    /**
     * 创建Bucket
     *
     * @param bucketName bucket名称
     */
    public void createBucket(String bucketName) {
        try {
            // 创建CreateBucketRequest对象
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
            // 设置存储类型（可选）
            createBucketRequest.setStorageClass(StorageClass.Standard);
            // 设置数据冗余类型（可选）
            createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS);
            // 创建Bucket
            ossClient.createBucket(createBucketRequest);
        } catch (OSSException e) {
            System.out.println("错误信息：" + e.getErrorMessage());
        } catch (ClientException e) {
            System.out.println("客户端异常：" + e.getMessage());
        }
    }

    /**
     * 检查Bucket是否存在
     *
     * @param bucketName bucket名称
     * @return 存在返回true，否则返回false
     */
    public boolean isBucketExist(String bucketName) {
        try {
            return ossClient.doesBucketExist(bucketName);
        } catch (OSSException | ClientException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 列出所有Bucket
     *
     * @return Bucket列表
     */
    public List<Bucket> listBuckets() {
        try {
            return ossClient.listBuckets();
        } catch (OSSException | ClientException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    /**
     * 删除Bucket
     *
     * @param bucketName bucket名称
     * @return 删除成功返回true, 否则返回false
     */
    public boolean deleteBucket(String bucketName) {
        try {
            ossClient.deleteBucket(bucketName);
            return true;
        } catch (OSSException | ClientException e) {
            e.printStackTrace();
            return false;
        }
    }
}
